//
//  builder.hpp
//  utilities
//
//  Created by Sam Jaffe on 6/2/13.
//  Copyright (c) 2013 Sam Jaffe. All rights reserved.
//

#pragma once

#include <mutex>

template <class _Tp>
class Builder {
public:
    
    virtual _Tp build() {
        return __build();
    }
    
private:
    virtual _Tp __build() = 0;
};

template <class _Tp>
class CheckedBuilder : Builder<_Tp> {
public:

    virtual bool isDone() const final {
        return complete;
    }
    
    virtual _Tp build() {
        validate();
        return __build();
    }

private:
    virtual _Tp __build() = 0;
    
    void validate() const {
        if (!isDone()) {
            //TODO throw exception;
        }
    }
    
private:
    bool complete = false;
};

template <class _Tp>
class SingleBuilder : public CheckedBuilder<_Tp> {
public:

    virtual _Tp build() final {
        static _Tp value = CheckedBuilder<_Tp>::build();
        return value;
    }

private:
    virtual _Tp __build() = 0;
};

template <class _Tp>
class OneShotBuilder : public CheckedBuilder<_Tp> {
public:
    
    bool alreadyBuilt() const {
        return built;
    }
    
    virtual _Tp build() final {
        validate();
        return CheckedBuilder<_Tp>::build();
    }
    
private:
    virtual _Tp __build() = 0;
    
    void validate() const {
        if (alreadyBuilt()) {
            //TODO throw exception
        }
    }
    
private:
    bool built;
};
